package com.test.dubbo.netty;


import com.test.dubbo.DubboDecoder;
import com.test.dubbo.DubboEncoder;
import com.test.dubbo.service.UserService;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Proxy;

@Component
public class NettyClient implements FactoryBean<UserService>
{


    private static NettyClientHandler client;

    //编写方法使用代理模式，获取一个代理对象

    public UserService getBean(final Class<?> serivceClass) {
        client.setBeanName (serivceClass.getSimpleName ());
        return (UserService) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class<?>[]{serivceClass}, client);
    }

    //初始化客户端
    @PostConstruct
    private   void initClient() {
        client = new NettyClientHandler();
        //创建EventLoopGroup
        NioEventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(
                        new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception {
                                ChannelPipeline pipeline = ch.pipeline();
                                pipeline.addLast(new DubboDecoder ());
                                pipeline.addLast(new DubboEncoder ());
                                pipeline.addLast(client);
                            }
                        }
                );

        try {
            bootstrap.connect("127.0.0.1", 7777).sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public UserService getObject () throws Exception
    {
        return this.getBean (UserService.class);
    }

    @Override
    public Class<?> getObjectType ()
    {
        return UserService.class;
    }
}
